mongodb

(一) 安装和设置

(1) 安装mongodb

宝塔面板可以直接安装

(2) 访问mongodb

  1. 腾讯云和宝塔面板都放行27017端口
  2. 进入宝塔面板mongodb的设置页面,找到127.0.0.1, 改为0.0.0.0,意思是所有ip都能访问
  3. 下载Robo3T1.3版本, 这是mongodb的可视化软件

(3) 用户管理

  1. 创建超级用户

use admin
db.createUser({user:"admin", pwd: "123456", roles: ["root"]})
db.auth("admin", "123456")
db.auth("admin", "hz001538")
  1. 创建单个数据库用户

use mall
db.createUser({user: "name", pwd: "123456", roles: [{ role: "dbOwner", db: "mall" }]})

(4) 开启安全验证码

  1. authorization: disabled 禁用, enabled启用
  2. 要是忘记密码, 可以先禁用, 重新创建即可 修改配置文件
   security:
   authorization: disabled
   javascriptEnabled: false

(二) 一对多集合设计

https://blog.csdn.net/smallSBoy/article/details/120768554

数据建模设计指南

  1. 在一对很少的情况下,你可以在父文档中内嵌数组。

  2. 在一对很多或者需要单独访问“N”端的数据时,你可以采用数组引用ObjectID的方式。如果可以加速你的访问也可以在“N”端使用父引用。

  3. 在一对非常多的情况下,可以在“N”端使用父引用。

(三) 内嵌文档操作

https://www.cnblogs.com/long-mao-bu-re/p/15142480.html

(四) 删除文档

  1. 删除1个

  2. 删除多个

(五) 多表查询

https://www.cnblogs.com/jasonminghao/p/13178087.html

https://www.runoob.com/nodejs/nodejs-mongodb.html

(1) 语法

语法值解释说明
from同一个数据库下等待被Join的集合。
localField源集合中的match值,如果输入的集合中,某文档没有 localField这个Key(Field),在处理的过程中,会默认为此文档含有 localField:null的键值对。
foreignField待Join的集合的match值,如果待Join的集合中,文档没有foreignField 值,在处理的过程中,会默认为此文档含有 foreignField:null的键值对。
as为输出文档的新增值命名。如果输入的集合中已存在该值,则会覆盖掉,

(2) 模拟数据

// 进入到devops库
use devops

// 插入数据
db.hosts.insertMany([
	{host: 'hdss7-21', private_ip: '172.16.7.21', public_ip: '202.100.23.21', region_id: '杭州', status: true},
	{host: 'hdss7-22', private_ip: '172.16.7.22', public_ip: '202.100.23.22', region_id: '杭州', status: true},
])


db.gameapp.insertMany([
	{host_id:ObjectId('5ef070ee381fbaacea727429'), name: 'qysg10001', version: '37184', port: 80001},
	{host_id:ObjectId('5ef070ee381fbaacea727429'), name: 'qysg10002', version: '37184', port: 80002},
	{host_id:ObjectId('5ef070ee381fbaacea727429'), name: 'qysg10003', version: '37184', port: 80003},
	{host_id:ObjectId('5ef070ee381fbaacea72742a'), name: 'qysg10004', version: '37184', port: 80004},
	{host_id:ObjectId('5ef070ee381fbaacea72742a'), name: 'qysg10005', version: '37184', port: 80005},
	{host_id:ObjectId('5ef070ee381fbaacea72742a'), name: 'qysg10006', version: '37184', port: 80006},
	{host_id:ObjectId('5ef070ee381fbaacea72742a'), name: 'qysg10007', version: '37184', port: 80007},
])

// 验证数据是否正确
db.hosts.find()
db.gameapp.find()

(3) 查询操作

01 $lookup使用

db.gameapp.aggregate([
	{ 
	$match: {name: 'qysg10001'} 
	},{
	$lookup: {
	 	from: 'hosts',
	 	localField: 'host_id',
	 	foreignField: '_id',
	 	as: 'host_info'
	}
}
])

02 $lookup中的参数

form:需要关联的表(hosts)
localField:gameapp关联到hosts的键(字段)
foreignField:hosts被关联到gameapp的localField的键(字段)
as:对应的外键集合数据(可能存在一对多的情况)

03 返回的数据

{ 
	"_id": ObjectId("5ef0737e381fbaacea727432"), 
	"host_id": ObjectId("5ef070ee381fbaacea727429"), 
	"name": "qysg10001", 
	"version": "37184", 
	"port": 80001, 

	"host_info": [{   
	"_id": ObjectId("5ef070ee381fbaacea727429"),
	"host": "hdss7-21",   
	"private_ip": "172.16.7.21",   
	"public_ip": "202.100.23.21",   
	"region_id": "杭州",   
	"status": true 
	}] 
}

04 处理host_info数据

可以看到host_info返回元素装在列表中,需要先把host_info外层列表除去,通过$unwind实现对host_info拆分

db.gameapp.aggregate([
	{ 
	$match: {name: 'qysg10001'} 
	},{
	$lookup: {
	 	from: 'hosts',
	 	localField: 'host_id',
	 	foreignField: '_id',
	 	as: 'host_info'
	}
	},{
	$unwind: {
		path: '$host_info',
		preserveNullAndEmptyArrays: true,
		}
	}
])

返回数据

{ 
	"_id": ObjectId("5ef0737e381fbaacea727432"), 
    "host_id": ObjectId("5ef070ee381fbaacea727429"), 
    "name": "qysg10001", 
    "version": "37184", 
    "port": 80001, 
    "host_info": { 
    	"_id": ObjectId("5ef070ee381fbaacea727429"), 
    	"host": "hdss7-21", 
    	"private_ip": "172.16.7.21", 
    	"public_ip": "202.100.23.21", 
    	"region_id": "杭州", 
    	"status": true 
   		} 
}

05 过滤数据

现在通过$project对数据进行过滤,我们只需要拿到host_info下的host、private_ip和status信息

db.gameapp.aggregate([
	{ 
	$match: {name: 'qysg10001'} 
	},{
	$lookup: {
	 	from: 'hosts',
	 	localField: 'host_id',
	 	foreignField: '_id',
	 	as: 'host_info'
	}
	},{
	$unwind: {
		path: '$host_info',
		preserveNullAndEmptyArrays: true,
		}
	},{
	$project: {
		_id: 0,
		'host_info.host': 1,
		'host_info.private_ip': 1,
		'host_info.status': 1,		
	}
}
])

返回数据

{ 
	"host_info": 
	{ 
		"host": "hdss7-21", 
		"private_ip": "172.16.7.21", 
		"status": true 
	} 
}

(六) 更新数据

(1) 更新一条数据

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
 
MongoClient.connect(url, function(err, db) {
    if (err) throw err;
    var dbo = db.db("runoob");
    var whereStr = {"name":'菜鸟教程'};  // 查询条件
    var updateStr = {$set: { "url" : "https://www.runoob.com" }};
    dbo.collection("site").updateOne(whereStr, updateStr, function(err, res) {
        if (err) throw err;
        console.log("文档更新成功");
        db.close();
    });
});

(2) 更新多条数据

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
 
MongoClient.connect(url, function(err, db) {
    if (err) throw err;
    var dbo = db.db("runoob");
    var whereStr = {"type":'en'};  // 查询条件
    var updateStr = {$set: { "url" : "https://www.runoob.com" }};
    dbo.collection("site").updateMany(whereStr, updateStr, function(err, res) {
        if (err) throw err;
         console.log(res.result.nModified + " 条文档被更新");
        db.close();
    });
});

(七) 查询

(1) 模糊查询

db.posts.find({post_text:{$regex:"runoob"}})
db.posts.find({post_text:{$regex:"runoob",$options:"$i"}}) // 不区分大小写
db.posts.find({post_text:/runoob/})
db.posts.find({post_text:/runoob/i})